package xyz.app.accessors;

import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.metamodel.SingularAttribute;
import lombok.NonNull;
import xyz.app.Dao;
import xyz.app.DaoRegistry;
import xyz.app.LogStatic;
import xyz.app.logic.PersistenceLogic;
import xyz.app.AbstractDomain;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Optional;

public interface DbAccessor<T extends AbstractDomain> extends LogStatic {

    @NonNull DaoRegistry daoRegistry();

    default <V extends AbstractDomain> Optional<Dao<V>> getDao(Class<V> domainClass) {
        return daoRegistry().getDao(domainClass);
    }

    @NonNull EntityManagerFactory getEmf();

    @NonNull Class<T> domainClass();

    PersistenceLogic<T> buildPersistenceLogic(@NonNull T t);

    @NonNull Collection<SingularAttribute<? super T, ?>> extractAttributes();

    default <U> U getMember(T owner, SingularAttribute<? super T, U> attribute) {

        if (null == owner) return null;
        if (!(attribute.getJavaMember() instanceof Field field)) return null;

        try {
            var member = field.get(owner);
            var javaType = attribute.getJavaType();
            return javaType.isInstance(member) ? javaType.cast(member) : null;
        }

        catch (IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
    }
}